﻿using System.Collections.Generic;

namespace XFramework
{

    public class FiniteStateMachine
    {
        //用个字典存所有状态
        public Dictionary<E_state, FsmBase> m_allState;

        /// <summary>
        /// 上一个状态
        /// </summary>
        private FsmBase m_priousState;

        /// <summary>
        /// 当前状态
        /// </summary>
        private FsmBase m_curState;

        //构造函数
        public FiniteStateMachine()
        {
            m_priousState = null;
            m_curState = null;
            m_allState = new Dictionary<E_state, FsmBase>();
        }

        #region 增

        /// <summary>
        /// 状态注册
        /// </summary>
        /// <param name="_fsmBase">想要被注册的状态</param>
        public void RegistState(FsmBase _fsmBase)
        {
            //没有这个状态就添加
            if (!m_allState.ContainsKey(_fsmBase.e_State))
                m_allState.Add(_fsmBase.e_State, _fsmBase);
        }

        #endregion

        #region 删

        //注销状态
        public void UnRegistState(FsmBase _fsmBase)
        {
            if (m_allState.ContainsKey(_fsmBase.e_State))
                m_allState.Remove(_fsmBase.e_State);
        }

        #endregion

        #region 改

        /// <summary>
        /// 改变状态
        /// </summary>
        /// <param name="_state">需要切换的下个状态</param>
        /// <param name="args">可选参数</param>
        public void ChangeState(E_state _state, params object[] args)
        {
            //没有这个状态 或 就是当前状态 就退出
            if (!m_allState.ContainsKey(_state) || _state == m_curState.e_State) return;
            if (m_curState == null) return;
            //本次状态退出
            m_curState.OnExit(args);
            //退出后把本次状态设为前一个状态
            m_priousState = m_curState;
            //根据想要更改的状态 去字典找 并设为当前状态
            m_curState = m_allState[_state];

            m_curState.OnEnter(args);
        }

        #endregion

        #region 查

        public E_state GetPriousState()
        {
            if (m_priousState != null)
                return m_priousState.e_State;

            return E_state.None;
        }

        public E_state GetCurState()
        {
            if (m_curState != null)
                return m_curState.e_State;

            return E_state.None;
        }

        #endregion

        #region 更新和启动

        public void UpdateState(params object[] args)
        {
            if (m_curState != null)
                m_curState.OnStay(args);
        }

        /// <summary>
        /// 开始运作并进入一个状态
        /// </summary>
        /// <param name="_fsmBase">想要进入的状态</param>
        /// <param name="args">可选参数</param>
        public void Go(FsmBase _fsmBase, params object[] args)
        {
            if (m_curState != null) return;
            m_curState = _fsmBase;
            m_curState.OnEnter(args);
        }

        #endregion
    }

}